﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Configuration;
using System.Web.Script.Serialization;
using System.Net;

namespace TestStatuses
{
    /// <summary>
    /// Summary description for GetBuildStatus
    /// </summary>
    public class GetBuildStatus : IHttpHandler
    {

        class Build
        {
            public Build(string project, string branch)
            {
                this.project = project;
                this.branch = branch;
            }

            public string project;
            public string branch;
        }

        private JavaScriptSerializer serializer;
        private string codeCityStatusUrl = WebConfigurationManager.AppSettings["codecity_status_url"];
        private const string failingKeyword = "failing";

        public GetBuildStatus()
        {
            serializer = new JavaScriptSerializer();
        }        

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "application/json";
            context.Response.Write(string.Format("{0}({1});", context.Request["callback"], GetFailedBuildsJson(codeCityStatusUrl)));
        }

        string GetFailedBuildsJson(string codeCityUrl)
        {
            List<Build> buildList = new List<Build>();

            string currentProjectName = "";
            string status = "";
            string moduleName = "";
            HttpWebRequest request;
            HttpWebResponse response;
            StreamReader reader;

            try
            {
                request = (HttpWebRequest)HttpWebRequest.Create("http://" + codeCityUrl);
                response = (HttpWebResponse)request.GetResponse();
                reader = new StreamReader(response.GetResponseStream());
            }
            catch (Exception e)
            {
                return "STATUS SERVER ERROR: error when creating httpwebrequest: " + e.Message;
            }

            try
            {
                string html = reader.ReadToEnd();

                foreach (string s in GetAllTagsContent(html.ToLower(), "tr"))
                {
                    
                    if (GetTagClass("td", s) == "tctd_projectname") //tr with project name
                    {
                        currentProjectName = GetAllTagsContent(s, "a")[0];
                    }
                    else //tr with build status
                    {
                        if (currentProjectName == "archive") //skip modules from archive
                        {
                            continue;
                        }
                        status = GetTagtitle("img", s);

                        if (status.IndexOf(failingKeyword) != -1)
                        {
                            moduleName = GetAllTagsContent(s, "a")[0];
                            buildList.Add(new Build(removeWhitespaces(currentProjectName), removeWhitespaces(moduleName)));
                        }
                    }
                }

                return serializer.Serialize(buildList);
            }
            catch (Exception e)
            {
                return "STATUS SERVER ERROR: " + e.Message;
            }
        }

        /// <summary>
        /// Returns content of tag tagName inside text (assumes that tagName isn't nested in another tagName) 
        /// </summary>
        private List<string> GetAllTagsContent(string text, string tagName)
        {
            List<string> list = new List<string>();
            int startTagBeggining, startTagClosing, endTag;
            string tempText;

            while((startTagBeggining = text.IndexOf("<" + tagName)) != -1)
            {
                tempText = text.Substring(startTagBeggining);
                startTagClosing = text.IndexOf(">", startTagBeggining);
                endTag = text.IndexOf("</" + tagName + ">", startTagBeggining);
                if (endTag > startTagBeggining)
                {
                    int contentStart = startTagClosing + 1;
                    list.Add(text.Substring(contentStart, endTag - contentStart));
                    text = text.Substring(endTag + tagName.Length + 3);
                }
                else
                {
                    return list;
                }
            }

            return list;
        }

        /// <summary>
        /// Returns tag tagName class (assumes that class value is given without "" and class is tag's first attribute)
        /// </summary>
        private string GetTagClass(string tagName, string text)
        {
            Regex r;
            Match m;

            r = new Regex(@"<"+tagName+@"\sclass=(?<class>[^<> ]*)",
            RegexOptions.IgnoreCase);
            m = r.Match(text.ToLower());
            if(m.Success)
            {
                return m.Groups[1].ToString();
            }
            else
            {
                return "";
            }
        }

        /// <summary>
        /// Returns tag tagName class (assumes that title value is given inside "" and title is tag's first attribute)
        /// </summary>
        private string GetTagtitle(string tagName, string text)
        {
            Regex r;
            Match m;
            
            r = new Regex(@"<img\s*title=""(?<title>[^""]*)",
            RegexOptions.IgnoreCase);
            m = r.Match(text.ToLower());
            if (m.Success)
            {
                return m.Groups[1].ToString();
            }
            else
            {
                return "";
            }
        }

        private string removeWhitespaces(string text)
        {
            text = text.Replace("  ", "");
            text = text.Replace(Environment.NewLine, "");
            return text;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}